package gui;

import game.CardDeckGame;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class CardDeck {
  enum Game {
    TEXAS_HOLDEM(TexasHoldem.class, "Texas Hold'em");

    Constructor<? extends CardDeckGame> ctor;
    String name;

    Game(Class<? extends CardDeckGame> clazz, String name) {
      this.name = name;
      try {
        this.ctor = clazz.getConstructor(int.class, JFrame.class);
      } catch (NoSuchMethodException ex) {
        throw new IllegalStateException("Unable to locate ctor", ex);
      }
    }

    CardDeckGame getInstance(int players, JFrame main) {
      try {
        return ctor.newInstance(players, main);
      } catch (InvocationTargetException ex) {
        throw new IllegalStateException("Unable to instansiate object", ex);
      } catch (IllegalAccessException ex) {
        throw new IllegalStateException("Unable to instansiate object", ex);
      } catch (InstantiationException ex) {
        throw new IllegalStateException("Unable to instansiate object", ex);
      }
    }
  }

  private class ChangeGameActionListener implements ActionListener {
    private Game game;

    public ChangeGameActionListener(Game game) {
      this.game = game;
    }

    public void actionPerformed(ActionEvent event) {
      System.out.println("Menu item [" + event.getActionCommand() +
          "] was pressed.");
    }
  }

  private JFrame main;
  private Game game;
  private CardDeckGame currentGame;

  public CardDeck() {
    this.main = new JFrame("CardDeck");
    this.main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.game = Game.TEXAS_HOLDEM;

    JMenuBar menuBar = new JMenuBar();
    JMenu gamesMenu = new JMenu("Games");
    for (Game g : Game.values()) {
      JMenuItem mitem = new JMenuItem(g.name);
      mitem.addActionListener(new ChangeGameActionListener(g));
      gamesMenu.add(mitem);
    }
    menuBar.add(gamesMenu);
    this.main.setJMenuBar(menuBar);
    this.main.pack();
  }

  public void run() {
    changeGame(game);
  }

  public void changeGame(Game g) {
    if (currentGame == null || !currentGame.getClass().equals(g.ctor.getDeclaringClass())) {
      int players = 2;
      this.main.setTitle("CardDeck: " + game.name);
      this.currentGame = game.getInstance(players, this.main);
    }
    this.currentGame.initGame();
    this.currentGame.runGame();
  }

  public static void main(String[] args) {
    CardDeck cd = new CardDeck();
    cd.run();
  }
}
